package com.minimalist.common.utils;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.context.AnalysisContext;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * Excel工具类使用示例
 * 演示如何使用ExcelGenerate进行Excel操作
 */
public class ExcelExample {

    /**
     * 示例数据模型
     */
    public static class UserData {
        @ExcelProperty("用户ID")
        private Long id;
        
        @ExcelProperty("用户名")
        private String username;
        
        @ExcelProperty("邮箱")
        private String email;
        
        @ExcelProperty("年龄")
        private Integer age;
        
        @ExcelProperty("创建时间")
        private Date createTime;

        // 构造函数
        public UserData() {}

        public UserData(Long id, String username, String email, Integer age, Date createTime) {
            this.id = id;
            this.username = username;
            this.email = email;
            this.age = age;
            this.createTime = createTime;
        }

        // Getter和Setter方法
        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public Date getCreateTime() {
            return createTime;
        }

        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }

        @Override
        public String toString() {
            return "UserData{" +
                    "id=" + id +
                    ", username='" + username + '\'' +
                    ", email='" + email + '\'' +
                    ", age=" + age +
                    ", createTime=" + createTime +
                    '}';
        }
    }

    /**
     * 订单数据模型
     */
    public static class OrderData {
        @ExcelProperty("订单ID")
        private String orderId;
        
        @ExcelProperty("商品名称")
        private String productName;
        
        @ExcelProperty("数量")
        private Integer quantity;
        
        @ExcelProperty("单价")
        private Double price;
        
        @ExcelProperty("总金额")
        private Double totalAmount;

        // 构造函数
        public OrderData() {}

        public OrderData(String orderId, String productName, Integer quantity, Double price, Double totalAmount) {
            this.orderId = orderId;
            this.productName = productName;
            this.quantity = quantity;
            this.price = price;
            this.totalAmount = totalAmount;
        }

        // Getter和Setter方法
        public String getOrderId() {
            return orderId;
        }

        public void setOrderId(String orderId) {
            this.orderId = orderId;
        }

        public String getProductName() {
            return productName;
        }

        public void setProductName(String productName) {
            this.productName = productName;
        }

        public Integer getQuantity() {
            return quantity;
        }

        public void setQuantity(Integer quantity) {
            this.quantity = quantity;
        }

        public Double getPrice() {
            return price;
        }

        public void setPrice(Double price) {
            this.price = price;
        }

        public Double getTotalAmount() {
            return totalAmount;
        }

        public void setTotalAmount(Double totalAmount) {
            this.totalAmount = totalAmount;
        }
    }

    /**
     * 自定义读取监听器
     */
    public static class UserDataListener implements ReadListener<UserData> {
        private List<UserData> dataList = new ArrayList<>();

        @Override
        public void invoke(UserData data, AnalysisContext context) {
            dataList.add(data);
            System.out.println("读取到数据: " + data);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            System.out.println("所有数据解析完成，共读取 " + dataList.size() + " 条数据");
        }

        public List<UserData> getDataList() {
            return dataList;
        }
    }

    /**
     * 示例1：写入单个工作表Excel
     */
    public static void example1_WriteSimpleExcel() {
        // 准备测试数据
        List<UserData> userData = Arrays.asList(
                new UserData(1L, "张三", "zhangsan@example.com", 25, new Date()),
                new UserData(2L, "李四", "lisi@example.com", 30, new Date()),
                new UserData(3L, "王五", "wangwu@example.com", 28, new Date())
        );

        // 写入Excel文件
        ExcelGenerate.writeExcel("用户数据.xlsx", "用户列表", UserData.class, userData);
        System.out.println("单个工作表Excel写入完成");
    }

    /**
     * 示例2：写入多个工作表Excel
     */
    public static void example2_WriteMultiSheetExcel() {
        // 准备用户数据
        List<UserData> userData = Arrays.asList(
                new UserData(1L, "张三", "zhangsan@example.com", 25, new Date()),
                new UserData(2L, "李四", "lisi@example.com", 30, new Date())
        );

        // 准备订单数据
        List<OrderData> orderData = Arrays.asList(
                new OrderData("ORD001", "笔记本电脑", 1, 5000.0, 5000.0),
                new OrderData("ORD002", "手机", 2, 3000.0, 6000.0)
        );

        // 创建工作表数据映射
        Map<String, ExcelGenerate.SheetData<?>> sheetDataMap = new HashMap<>();
        sheetDataMap.put("用户数据", ExcelGenerate.createSheetData(UserData.class, userData));
        sheetDataMap.put("订单数据", ExcelGenerate.createSheetData(OrderData.class, orderData));

        // 写入多工作表Excel
        ExcelGenerate.writeMultiSheetExcel("多工作表数据.xlsx", sheetDataMap);
        System.out.println("多工作表Excel写入完成");
    }

    /**
     * 示例3：读取Excel文件
     */
    public static void example3_ReadExcel() {
        UserDataListener listener = new UserDataListener();
        
        // 读取Excel文件
        ExcelGenerate.readExcel("用户数据.xlsx", UserData.class, listener);
        
        // 获取读取的数据
        List<UserData> dataList = listener.getDataList();
        System.out.println("读取到的数据条数: " + dataList.size());
    }

    /**
     * 示例4：使用模板填充数据
     */
    public static void example4_FillTemplate() {
        // 准备填充数据
        Map<String, Object> fillData = new HashMap<>();
        fillData.put("title", "用户报告");
        fillData.put("date", new Date());
        fillData.put("totalUsers", 100);
        fillData.put("activeUsers", 85);

        // 假设有模板文件 template.xlsx
        // ExcelGenerate.fillTemplate("template.xlsx", "报告.xlsx", fillData);
        System.out.println("模板填充示例（需要模板文件）");
    }

    /**
     * 示例5：复杂模板填充
     */
    public static void example5_FillComplexTemplate() {
        // 准备单个数据
        Map<String, Object> headerData = new HashMap<>();
        headerData.put("companyName", "示例公司");
        headerData.put("reportDate", new Date());
        headerData.put("reportTitle", "月度销售报告");

        // 准备列表数据
        List<Map<String, Object>> salesData = new ArrayList<>();
        for (int i = 1; i <= 5; i++) {
            Map<String, Object> sale = new HashMap<>();
            sale.put("productName", "产品" + i);
            sale.put("salesAmount", 1000 * i);
            sale.put("profit", 200 * i);
            salesData.add(sale);
        }

        // 假设有复杂模板文件
        // ExcelGenerate.fillComplexTemplate("complex_template.xlsx", "销售报告.xlsx", headerData, salesData);
        System.out.println("复杂模板填充示例（需要模板文件）");
    }

    /**
     * 示例6：使用输出流操作
     */
    public static byte[] example6_WriteToOutputStream() throws IOException {
        List<UserData> userData = Arrays.asList(
                new UserData(1L, "张三", "zhangsan@example.com", 25, new Date())
        );

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            ExcelGenerate.writeExcel(outputStream, "用户数据", UserData.class, userData);
            byte[] excelBytes = outputStream.toByteArray();
            System.out.println("Excel数据写入到字节数组，大小: " + excelBytes.length + " 字节");
            return excelBytes;
        }
    }

    /**
     * 示例7：从输入流读取
     */
    public static void example7_ReadFromInputStream(byte[] excelBytes) {
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(excelBytes)) {
            UserDataListener listener = new UserDataListener();
            ExcelGenerate.readExcel(inputStream, UserData.class, listener);
            System.out.println("从输入流读取Excel完成");
        } catch (IOException e) {
            System.err.println("读取Excel时发生错误: " + e.getMessage());
        }
    }

    /**
     * 主方法 - 运行所有示例
     */
    public static void main(String[] args) {
        try {
            System.out.println("=== Excel工具类使用示例 ===");
            
            // 示例1：写入单个工作表
            example1_WriteSimpleExcel();
            
            // 示例2：写入多个工作表
            example2_WriteMultiSheetExcel();
            
            // 示例3：读取Excel（需要先有文件）
            // example3_ReadExcel();
            
            // 示例4：模板填充
            example4_FillTemplate();
            
            // 示例5：复杂模板填充
            example5_FillComplexTemplate();
            
            // 示例6和7：流操作
            byte[] excelBytes = example6_WriteToOutputStream();
            example7_ReadFromInputStream(excelBytes);
            
            System.out.println("=== 所有示例执行完成 ===");
            
        } catch (Exception e) {
            System.err.println("执行示例时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}